package com.atguigu.gulimall.order.config;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * 消费端默认自动确认消息接受，rabbitmq服务器一旦确认消费端收到消息就会将消息删除
 * 如果消费端消费时出异常，则该消息将会丢失
 */
@Component
public class RabbitProp {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * init-method
     */
    @PostConstruct
    public void initRabbit(){
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback(){

            /**
             * 配置
             * #    开启消息确认  confirmCallback
             *     publisher-confirms: true
             *
             *  只要消息抵达rabbitmq服务器，就会触发confirmCallback  ack  为true
             * @param correlationData  当前消息的唯一关联数据(唯一id)   在消息发送时可以携带一个CorrelationData参数，里面可以指定消息id
             * @param ack     消息是否成功
             * @param cause   失败原因
             */
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                System.out.println("消息确认  confirm...    correlationData : ["+correlationData+"]   ack : "+ack +"   cause : "+cause);
            }
        });


        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {

            /**
             * 配置    publisher-returns: true
             * #    只要消息没有抵达队列，以异步的方式优先回调returnCallback
             *     template:
             *       mandatory: true
             *   #    publisher-confirm-type: correlated
             *
             *  returnCallback  消息从交换机投递到队列失败就会触发returnCallback
             *
             * @param message  投递失败的消息详细信息
             * @param replyCode 恢复状态码
             * @param replyText 恢复文本
             * @param exchange 消息发送给哪个交换机
             * @param routingKey 消息发送时指定的路由键
             */
            @Override
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                System.out.println("failMessage : ["+message+"]  ----- replyCode : "+replyCode);
            }
        });
    }
}
